package ${projectDomain}.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import ${projectDomain}.adapter.login.LoginAdapter;
import ${projectDomain}.adapter.system.SystemResourceAdapter;
import ${projectDomain}.adapter.system.SystemRoleAdapter;
import ${projectDomain}.adapter.system.SystemUserAdapter;
import ${projectDomain}.adapter.validate.IValidateAdapter;
import ${projectDomain}.core.CommonOperator;
import ${projectDomain}.core.entity.TokenUser;
import ${projectDomain}.enums.system.role.AuthorityTypeEnum;
import ${projectDomain}.pojo.bo.login.login.LogingBo;
import ${projectDomain}.pojo.cho.login.TokenResourceCho;
import ${projectDomain}.pojo.cho.login.TokenRoleCho;
import ${projectDomain}.pojo.cho.login.TokenUserCho;
import ${projectDomain}.pojo.dao.system.resource.SystemResourceDataDo;
import ${projectDomain}.pojo.dao.system.role.SystemRoleDataDo;
import ${projectDomain}.pojo.vo.login.LoginVo;
import ${projectDomain}.pojo.vo.login.LogoutVo;
import ${projectDomain}.pojo.vo.login.TokenResourceVo;
import ${projectDomain}.pojo.vo.login.TokenRoleVo;
import ${projectDomain}.pojo.vo.login.TokenUserVo;
import ${projectDomain}.utils.ServletUtils;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.ObjectUtils;

import jakarta.servlet.http.HttpServletRequest;

@Service
@Api(value="登录服务类", author="unswift", date="2023-05-31", version="1.0.0")
public class LoginService extends CommonOperator{

	@Autowired
	@ApiField("登录公共操作")
	private LoginAdapter loginAdapter;
	
	@Autowired
	@ApiField("用户公共操作")
	private SystemUserAdapter systemUserAdapter;
	
	@Autowired
	@ApiField("角色公共操作")
	private SystemRoleAdapter systemRoleAdapter;
	
	@Autowired
	@ApiField("资源公共操作")
	private SystemResourceAdapter systemResourceAdapter;
	
	@Autowired
	@ApiField("表单验证公共操作")
	private IValidateAdapter validateAdapter;
	
	@ApiField("token失效时间")
	@Value("${r'${unswift.token.expire}'}")
	private String expire;
	
	@ApiMethod(value="登录业务", params={@ApiField("登录业务实体"), @ApiField("当前请求")}, returns=@ApiField("用户token"))
	public LoginVo loging(LogingBo loginBo, HttpServletRequest request){
		String captchaKey = ServletUtils.getHeader("captchaKey");
		ExceptionUtils.empty(captchaKey, "validate.code.error");
		loginBo.setSessionCode(this.redisAdapter.delete(captchaKey));//设置验证码到Bo对象并删除验证码缓存
		validateAdapter.validate("login", "", loginBo, this.getUser(), systemUserAdapter);//验证表单
		TokenUserCho user=loginAdapter.validatePassword(loginBo);//根据Bo对象验证密码，如果密码验证通过，则返回Token用户
		List<SystemRoleDataDo> roleList=systemRoleAdapter.findByUserId(user.getId(), user.getIsAdmin(), AuthorityTypeEnum.OCCUPANT);//获取用户拥有角色
		ExceptionUtils.empty(roleList, "no.permissions.have.been.assigned.yet");
		user.setRoleList(this.convertPojoList(roleList, TokenRoleCho.class));//将角色列表转换为Token角色对象
		List<SystemResourceDataDo> resourceList=systemResourceAdapter.findByRoles(roleList, user.getIsAdmin());
		user.setResourceList(this.convertPojoList(resourceList, TokenResourceCho.class));//将资源列表转换为Token资源对象
		redisAdapter.set(user.getToken(), user, tokenConfig.getExpireInt());//token一个小时失效，必须使用刷新token接口刷新
		return new LoginVo(user.getToken(), tokenConfig.getHeader(), tokenConfig.getKeyName(), tokenConfig.getExpireInt());
	}
	
	@ApiMethod(value="登出业务", returns = @ApiField("登出结果信息"))
	public LogoutVo logout() {
		TokenUser user=this.getUser();
		if(ObjectUtils.isNotEmpty(user)) {
			redisAdapter.delete(user.getToken());
		}
		return new LogoutVo(1);
	}
	
	@ApiMethod(value="根据Token获取用户信息", returns = @ApiField("用户信息"))
	public TokenUserVo getUserInfo() {
		TokenUser user=this.getUser();
		user.setIsAdmin(null);
		return this.convertPojo(user, TokenUserVo.class, new PojoFieldExtend<List<TokenRoleCho>, List<TokenRoleVo>>("roleList") {
			@Override
			public List<TokenRoleVo> customAuto(List<TokenRoleCho> s) {
				return convertPojoList(s, TokenRoleVo.class);
			}
		}, new PojoFieldExtend<List<TokenResourceCho>, List<TokenResourceVo>>("resourceList") {
			@Override
			public List<TokenResourceVo> customAuto(List<TokenResourceCho> s) {
				return convertPojoList(s, TokenResourceVo.class);
			}
		});
	}
}
